package com.example.dingding.controller;

import com.dingtalk.oapi.lib.aes.Utils;
import com.example.dingding.config.Constant;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.dingding.entity.UseCar;
import com.example.dingding.entity.dto.UseCarSmsDTO;
import com.example.dingding.mapper.UseCarMapper;
import com.example.dingding.service.SmsService;
import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
import com.taobao.api.internal.toplink.embedded.websocket.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author cgyt
 * @date 2024/4/19 10:02
 */
@RestController
@RequestMapping("/SMS")

public class SMSController {
    @Autowired
    private UseCarMapper useCarMapper;

    //短信服务
    @Autowired
    private final SmsService smsService;

    //事件回调
    private final Logger log = LoggerFactory.getLogger(getClass());

    /**
     * 创建应用，验证回调URL创建有效事件（第一次保存回调URL之前）
     */
    private static final String EVENT_CHECK_CREATE_SUITE_URL = "check_create_suite_url";

    /**
     * 创建应用，验证回调URL变更有效事件（第一次保存回调URL之后）
     */
    private static final String EVENT_CHECK_UPADTE_SUITE_URL = "check_update_suite_url";

    /**
     * suite_ticket推送事件
     */
    private static final String EVENT_SUITE_TICKET = "suite_ticket";

    /**
     * 企业授权开通应用事件
     */
    private static final String EVENT_TMP_AUTH_CODE = "tmp_auth_code";

    //设置锁
    public  static  boolean isCalled = false;

    //发送短信
    @Autowired
    public SMSController( SmsService smsService) {
        this.smsService = smsService;

    }


    //发送短信
    @PostMapping("/sendMessage")
    public String sendMessage(@RequestBody UseCarSmsDTO useCarSmsDTO) throws IOException {
        if (log.isInfoEnabled()){
            log.info("SMSController.sendMessage.dto:{}", JSON.toJSONString(useCarSmsDTO));
        }
        return smsService.sendMessage(useCarSmsDTO);
    }

    //事件订阅（详细请参考钉钉开发者平台文档，本代码来自钉钉示例代码，部分进行修改）
    @RequestMapping(value = "/dingCallback", method = RequestMethod.POST)
    @ResponseBody
    public synchronized Map<String, String> callback(@RequestParam(value = "signature",required = false) String signature,
                                        @RequestParam(value = "timestamp",required = false) Long timestamp,
                                        @RequestParam(value = "nonce",required = false) String nonce,
                                        @RequestBody JSONObject body) {
        String params = "signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " body:" + body;



        try {
//            log.info("begin callback:" + params);
            DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(Constant.TOKEN, Constant.ENCODING_AES_KEY,Constant.SUITE_KEY);


            // 从post请求的body中获取回调信息的加密数据进行解密处理
            String encrypt = body.getString("encrypt");
//            log.info("encrypt:" + encrypt);
            String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt);
//            // 从post请求的body中获取回调信息的加密数据进行解密处理
//            String encrypt = body.getString("encrypt");
            JSONObject callBackContent = JSON.parseObject(plainText);

            //这一段代码以上为正确的认证代码

////            // 打印解密后的回调信息
//            log.info("callback content:" + callBackContent.toJSONString());

//
//
            //获取信息中的processInstanceId，并根据processInstanceId查询本次的司机信息和车牌号
            JSONObject jsonObject = new JSONObject(callBackContent);
            String processInstanceId = jsonObject.getString("processInstanceId");

            //获取司机信息和车牌号,公里数和缴费金额
            UseCar message = smsService.carMessage(processInstanceId);



//            log.info(message.toString());

            //司机电话,现公里数
            String carMessage = message.getCarMessage();
            String currentMileage = message.getCurrentMileage();
            //格式处理
            carMessage  = carMessage .substring(1, carMessage .length() - 1);
            currentMileage=currentMileage.substring(1, currentMileage .length() - 1);
            log.info("currentMileage:{}", currentMileage);
            //查询审批次数
            Integer approvalCount = useCarMapper.selectOACount(processInstanceId);
            String expenses = message.getExpenses();

                /**
                 * 发送短信通知缴费
                 *
                 * **/
                String oa2 = approvalCount.toString();
                boolean a = "1".equals(oa2) && !"由车管填写".equals(currentMileage);
//                log.info("a:11111111111111111111111111111111111111111111{}", a);
                if ("1".equals(oa2) && !"由车管填写".equals(currentMileage)) {

                    //获取乘车发起人员信息
                    String riderPeople = useCarMapper.selectProcessInstanceid(processInstanceId);
                    String original = useCarMapper.selectOverrive(processInstanceId);

//                    log.info("riderPeople:{}99999999999999999999", riderPeople);
//                    log.info("original:{}88888888888888888888", original);

                    //// 使用正则表达式匹配括号内的所有数字
                    Pattern pattern = Pattern.compile("\\d+");
                    Matcher matcher = pattern.matcher(riderPeople);
                    List<String> numberList = new ArrayList<>();

                    while (matcher.find()) {
                        // 将匹配到的数字添加到List集合中
                        numberList.add(matcher.group());
                    }
//                    log.info("numberList:{}88888888888333333333333333", numberList);

//                    log.info("expenses:{}2222222222222222222222222222", expenses);
                    String kilometers = message.getKilometers();
//                    log.info("kilometers:{}2222222222222222222222222222", kilometers);
                    if (expenses.equals(null)) {
                        expenses = "0";
                    }

                    String serialNumber = smsService.sSerialNumber();
                    //短信内容拼接
                    UseCarSmsDTO endNote = new UseCarSmsDTO();
                    //企业编号
                    endNote.setSpCode("263092");
                    //用户名
                    endNote.setLoginName("cs_rmyh");
                    //密钥
                    endNote.setPassword("e233ee84cf769cffee50f55352ca88fa");
                    //
                    endNote.setMessageContent("您本次用车已结束,车辆行驶公里数" + expenses.replace("\"", "") + ",应缴纳费用：" + kilometers.replace("\"", "") + "。");

                    //短信模块id
                    endNote.setTemplateId("2151012280393");


                    //流水号
                    endNote.setSerialNumber(serialNumber);

                    endNote.setF("f");
//                    log.info("sdfsdfsdf", "sdfsdfsdfsdf");
                    for (String s : numberList) {
                        if (s.equals(original)) {
                            log.info("发起人已加入乘车人员中:{}", original);
                            //电话号码
                        } else {
                            numberList.add(original);
                        }
                        endNote.setUserNumber(s);

                        log.info("endNote:{}", JSON.toJSONString(endNote));
                        smsService.sendMessage(endNote);

                        useCarMapper.updateOACount(processInstanceId);
                    }
                }
//            log.info("approvalCount:{}",approvalCount);
//            if(approvalCount.equals(0)) {
                if (processInstanceId != null && !carMessage.equals("由车管填写") && currentMileage.equals("由车管填写") && approvalCount.equals(0)) {


                    //车牌
                    String carNumber = message.getCarNumber();
                    //用车时间
                    String useTime = message.getUseTime();
                    //具体目的地
                    String specificDestination = message.getSpecificDestination();
                    //出发地点
                    String startingPoint = message.getStartingPoint();
                    //获取流水号
                    String serialNumber = smsService.sSerialNumber();
                    //短信内容拼接
                    UseCarSmsDTO car = new UseCarSmsDTO();
                    //企业编号
                    car.setSpCode("263092");
                    //用户名
                    car.setLoginName("cs_rmyh");
                    //密钥
                    car.setPassword("e233ee84cf769cffee50f55352ca88fa");
                    //短信内容
                    //模板内容:
                    //您明天驾驶(xxxxxxxx}的车辆于{xxxxxxxxxxxxxxxx}
                    // 前往{xxxxxxxxxxxxxxxxxxxxxHx}请提前到达{xxxxxxxxxxxxxxxxxxxxx}等候
                    car.setMessageContent("您明天驾驶" + carNumber.replace("\"", "") + "的车辆于" + useTime.replace("\"", "") + "前往" + specificDestination.replace("\"", "") + "请提前到达" + startingPoint.replace("\"", "") + "等候。");
                    //电话号码
                    car.setUserNumber(carMessage);
                    log.info("carMessage:{}", carMessage);
                    //短信模块id
                    car.setTemplateId("2151012276881");
                    //流水号
                    car.setSerialNumber(serialNumber);
                    car.setF("f");
                    log.info("car:{}", JSON.toJSONString(car));
                    smsService.sendMessage(car);

                    //短信通知乘车人
                    //获取乘车人员信息
                    String riderPeople = useCarMapper.selectProcessInstanceid(processInstanceId);
                    //// 使用正则表达式匹配括号内的所有数字
                    Pattern pattern = Pattern.compile("\\d+");
                    Matcher matcher = pattern.matcher(riderPeople);
                    List<String> numberList = new ArrayList<>();

                    while (matcher.find()) {
                        // 将匹配到的数字添加到List集合中
                        numberList.add(matcher.group());
                    }

                    //乘车人员
                    UseCarSmsDTO riderHuman = new UseCarSmsDTO();
                    //企业编号
                    riderHuman.setSpCode("263092");
                    //用户名
                    riderHuman.setLoginName("cs_rmyh");
                    //密钥
                    riderHuman.setPassword("e233ee84cf769cffee50f55352ca88fa");
                    // 您明天前往{xxxxxxxxxxxxxxxxxxxxx}的车辆号牌为{x}{xxxxxxxxxxx}
                    // {x}司机号码{x}{xxxxxxxxxxxxx}{x}{xxxxxxxxxxxxxxxxxxxx}在
                    // {xxxxxxxxxxxxxxxxxxxxxxx}出发{x}敬请知悉{x}
                    riderHuman.setMessageContent("您明天前往" + specificDestination.replace("\"", "") + "的车辆号牌为:" + carNumber.replace("\"", "") + ",司机号码:" + carMessage.replace("\"", "") + "," + useTime.replace("\"", "") + "在" + startingPoint.replace("\"", "") + "出发,敬请知悉。");
                    //短信模块id
                    riderHuman.setTemplateId("2151012276862");
                    //流水号
                    riderHuman.setSerialNumber(serialNumber);
                    riderHuman.setF("f");

                    for (String s : numberList) {
                        //电话号码
                        riderHuman.setUserNumber(s);
                        log.info("riderHuman:{}", JSON.toJSONString(riderHuman));
                        smsService.sendMessage(riderHuman);
                    }
                    useCarMapper.updateCount(processInstanceId);
//                    if (!isCalled){
//                        isCalled = true;
//                        scheduleUnlock();
//                    }else {
//                        System.out.println("接口已被调用过");
//                    }
                }

            //到这里结束






//
//            // 打印回调事件类型
//            log.info("callback event type:" + eventType);
//            if (EVENT_CHECK_CREATE_SUITE_URL.equals(eventType)) {
//                log.info("验证新创建的回调URL有效性: " + plainText);
//            } else if (EVENT_CHECK_UPADTE_SUITE_URL.equals(eventType)) {
//                log.info("验证更新回调URL有效性: " + plainText);
//            } else if (EVENT_SUITE_TICKET.equals(eventType)) {
//                // suite_ticket用于用签名形式生成accessToken(访问钉钉服务端的凭证)，需要保存到应用的db。
//                // 钉钉会定期向本callback url推送suite_ticket新值用以提升安全性。
//                // 应用在获取到新的时值时，保存db成功后，返回给钉钉success加密串（如本demo的return）
//                log.info("应用suite_ticket数据推送: " + plainText);
//            } else if (EVENT_TMP_AUTH_CODE.equals(eventType)) {
//                // 本事件应用应该异步进行授权开通企业的初始化，目的是尽最大努力快速返回给钉钉服务端。用以提升企业管理员开通应用体验
//                // 即使本接口没有收到数据或者收到事件后处理初始化失败都可以后续再用户试用应用时从前端获取到corpId并拉取授权企业信息，进而初始化开通及企业。
//                log.info("企业授权开通应用事件: " + plainText);
//            } else {//
//                // 其他类型事件处理
//            }

            // 返回success的加密信息表示回调处理成功
            return dingTalkEncryptor.getEncryptedMap("success", timestamp, nonce);
        } catch (Exception e) {
            //失败的情况，应用的开发者应该通过告警感知，并干预修复
//            log.error("process callback fail." + params, e);
            return null;
        }
    }

//    private void scheduleUnlock() {
//        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
//        scheduler.schedule(() -> {
//            synchronized (this) {
//                isCalled = false;
//                System.out.println("一分钟后锁被释放");
//            }
//        }, 1, TimeUnit.MINUTES);
//    }


}
